package org.glutenberg.util.binarytree;

import org.glutenberg.util.Comparable;

public class TreeItem implements Comparable {
	private TreeItem leftChild;
	private TreeItem rightChild;
	private TreeItem parent;

	private Object key;

	private Tree tree;
	
	public TreeItem(Tree tree, Object key){
		this.key = key;
		this.tree = tree;
	}	
	
	public boolean isLeftChild() {
		return this.parent!=null && this.parent.getLeftChild()==this;
	}
	
	public boolean isRightChild() {
		return this.parent!=null && this.parent.getRightChild()==this;
	}
	
	public TreeItem getLeftChild() {
		return leftChild;
	}

	public void setLeftChild(TreeItem leftChild) {
		this.leftChild = leftChild;
	}

	public TreeItem getRightChild() {
		return rightChild;
	}

	public void setRightChild(TreeItem rightChild) {
		this.rightChild = rightChild;
	}
	
	public TreeItem getParent() {
		return parent;
	}

	public void setParent(TreeItem parent) {
		this.parent = parent;
	}	

	public boolean insert(TreeItem treeItem) {
		int compare = this.compareTo(treeItem);
		if(compare>0){
			if(this.leftChild==null){
				this.leftChild = treeItem;
				this.leftChild.setParent(this);
				return true;
			}
			else return this.leftChild.insert(treeItem);
		} else if(compare<0 || (compare==0 && this.tree.getAllowDuplicates())){
			if(this.rightChild==null){
				this.rightChild = treeItem;
				this.rightChild.setParent(this);
				return true;
			}
			else return this.rightChild.insert(treeItem);
		} else {
			this.tree.resolveConflict(this, treeItem);
			return false;
		}
	}
	
	public TreeItem searchFirst(Object key){
		int compare = this.tree.compare(this.key, key);
		if(compare==0) return this;
		else if(compare<0 && this.rightChild!=null) return this.rightChild.searchFirst(key);
		else if(compare>0 && this.leftChild!=null) return this.leftChild.searchFirst(key);
		else return null;
	}

	public int compareTo(Object o) {
		TreeItem t = (TreeItem) o;
		return this.tree.compare(this.key, t.key);
	}
	
	public Object getKey() {
		return key;
	}

}
